package com.luca.web.controller.common;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.luca.common.utils.ServletUtils;
import com.luca.common.utils.StringUtils;
import com.luca.system.domain.WechatInfo;
import com.luca.system.service.IWechatInfoService;
import com.luca.system.service.WechatUserService;
import com.luca.system.wechat.CustomMessageHandler;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

/**
 * 微信公众号相关
 */
@Slf4j
@RestController
@RequestMapping("/wechat")
public class WechatController {

    private final WechatUserService wechatUserService;
    private final IWechatInfoService wechatInfoService;
    private final CustomMessageHandler handler;

    @Autowired
    public WechatController(WechatUserService wechatUserService, IWechatInfoService wechatInfoService, CustomMessageHandler handler) {
        this.wechatUserService = wechatUserService;
        this.wechatInfoService = wechatInfoService;
        this.handler = handler;
    }

    private WxMpDefaultConfigImpl config;

    private WxMpService wxMpService;

    private WxMpMessageRouter router;

    /**
     * 接收公众号消息推送
     */
    @RequestMapping("/callback")
    public void callback(@RequestParam("id") String id, @RequestParam(value = "echostr", required = false) String echostr) throws IOException {
        processService(id);
        checkVerificationMsg(echostr);
        // 先回复，再处理业务
        WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(ServletUtils.getRequest().getInputStream());
        router = new WxMpMessageRouter(wxMpService);
        var outMessage = router.route(inMessage);
        if (outMessage != null) {
            ServletUtils.getResponse().getWriter().write(outMessage.toXml());
        }
        route(router);
    }

    /**
     * 菜单
     * */

    /**
     * 验证消息的确来自微信服务器
     */
    private void checkVerificationMsg(String echostr) throws IOException {
        if (StringUtils.isNotBlank(echostr)) {
            String timestamp = ServletUtils.getRequest().getParameter("timestamp");
            String nonce = ServletUtils.getRequest().getParameter("nonce");
            String signature = ServletUtils.getRequest().getParameter("signature");
            if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
                log.error("消息不合法");
                return;
            } else {
                log.info("ok");
                ServletUtils.getResponse().getWriter().write(echostr);
                return;
            }
        }
    }

    /**
     * 构建service
     */
    private void processService(String id) {
        var wechatInfo = wechatInfoService.getOne(new QueryWrapper<WechatInfo>().eq("tenant_id", id));
        if (null == wechatInfo) {
            log.error("公众号信息不存在:{}", id);
            return;
        }
        config = new WxMpDefaultConfigImpl();
        config.setAppId(wechatInfo.getAppId());
        config.setSecret(wechatInfo.getSecret());
        config.setToken(wechatInfo.getToken());
        wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(config);
    }

    /**
     * 消息路由
     */
    private void route(WxMpMessageRouter router) {
        router.rule()
                .async(false)
                .content("luca")
                .handler(handler)
                .end();
    }

}
